ユニフォーム変数を使用して、シェーダーにアニメーションを追加する方法を学びます。
パーティクルに動きを加える
パーティクルをアニメーションさせるために、ユニフォーム変数 (Uniform variables) という概念を導入します。
ユニフォームは、JavaScript からシェーダーに渡される値です。グローバル変数のようなものだと考えてください。その値を変更すると、スケッチをリフレッシュすることなく、シェーダーのすべてのインスタンスが即座にその変更を認識します。これにより、ユニフォームはシェーダーのインタラクティブな部分に最適です。
const time = uniformFloat(() => millis());p5.strands では、uniformFloat、uniformVector3 などを使用してユニフォームを宣言します。これらはコールバック関数の中で宣言する必要がありますが、ストランド関数自体の内部ではありません。
オプションとして、ユニフォームに初期値(デフォルト値)を指定できます。デフォルト値を関数として設定すると、その関数は毎フレーム実行され、ユニフォームの値が更新されます。あるいは、p5.js の通常のシェーダーと同様に、myShader.setUniform('time', millis()) を呼び出して値を設定することも可能です。
スケッチのソースコードを見てみましょう:
let instancingShader;
let instancingStrokeShader;
let particleModel;
function instancingCallback() {
// ユニフォーム変数の宣言を追加
const time = uniformFloat(() => millis());
// 擬似乱数関数
function rand(seed) {
return fract(sin(dot(seed, [12.9898, 78.233])) * 43758.5453123);
}
function getAnimatedSpherePosition() {
let id = instanceID();
let theta = rand([id, 0.1234]) * TWO_PI;
// 時間の経過とともにパーティクルの位置を変化させます
let phi = rand([id, 3.321]) * PI + time / 10000;
// より興味深い形を作るために半径を変化させます
let r = 200 * sin(phi);
let x = r * sin(phi) * cos(theta);
// Y 軸方向を少し引き伸ばします
let y = r * 1.5 * cos(phi);
let z = r * sin(phi) * sin(theta);
return [x, y, z];
}
getWorldInputs((inputs) => {
inputs.position += getAnimatedSpherePosition();
return inputs;
});
}
async function setup() {
createCanvas(400, 400, WEBGL);
pixelDensity(1);
particleModel = buildGeometry(() => sphere(10, 4, 2));
instancingShader = baseColorShader().modify(instancingCallback);
instancingStrokeShader = baseStrokeShader().modify(instancingCallback);
}
function draw() {
background(0);
orbitControl();
shader(instancingShader);
fill(255, 100, 150);
strokeShader(instancingStrokeShader);
model(particleModel, 1000);
}phi 角に time / 10000 を加え、さらに半径を sin() で変化させることで、脈動しながら引き伸ばされた球体の周りを移動するアニメーションを作成しています。
sin() を tan() や acosh()、あるいはそれらの組み合わせに置き換えてみてください。シェーダーコードのわずかな変更が、劇的に異なる視覚効果を生み出すことがよくあります。ユニフォームとして利用可能な p5.js 変数
p5.strands を使用すると、p5.js のよく知られたグローバル変数のいくつかが、最初からユニフォームとして利用可能です。
コールバック関数内では、以下のいずれかを直接使用できます:
- 寸法 (Dimensions):
width,height,displayWidth,displayHeight,windowWidth,windowHeight - 時間とフレーム (Time and frameCount):
deltaTime,frameCount - ポインタ (Pointer):
mouseIsPressed,mouseX,mouseY,pmouseX,pmouseY,pwinMouseX,pwinMouseY,winMouseX,winMouseY
これらは mouseIsPressed(boolean)を除いて、すべて浮動小数点数(float)です。
License
Original URL: https://beta.p5js.org/tutorials/intro-to-p5-strands/
License: MIT License
Copyright (c) 2015-present p5.js contributors & The Processing Foundation